/*
*
*	The client thread class deals will all input / output to the client connection.
*	for the class to get past initialisation an authentication packet must be processed and pass, if not the thread will exit and free up its resources.
*
*/

#include "ClientConnection.h"

CClientConnection::CClientConnection(SOCKET s) : CThreadObject()
{
	userSocket = s;
	userObject = 0;
	this->AuthenticateLoginPacket();
	this->Run();
}

CClientConnection::~CClientConnection()
{
	sysRoot->removeClientConnectionThread((void*)this);
}

void CClientConnection::InitThread()
{

}

void CClientConnection::FlushThread()
{

}

CPacket* CClientConnection::getWaitingPacket()
{
	return new CPacket(userSocket);
}

bool CClientConnection::AuthenticateLoginPacket()
{
	/* check to see if the first few bytes in the socket is a valid authentication packet */
	CPacket* loginPacket = getWaitingPacket();
	if(loginPacket) {
		if(loginPacket->getPacketType() == PACKET_AUTHENTICATE)
		{
			// 2DO Check Authentication
			userAuthenticated = true;
			userId = 1;
			userClientType = (BYTE)loginPacket->unpackLong();
		}
	}

	/* if we have been authenticated then register with the system root object */
	if(userAuthenticated)
	{
		sysRoot->addClientConnectionThread((void*)this);

		// try to connect with an existing user session if this is a terminal connection

		if(userClientType == CONNECTION_CLIENT)
		{
			userObject = (CUser*)sysRoot->getUserObjectForId(userId);
			if(!userObject) { userObject = new CUser((void*)this); sysRoot->addUserObject(userObject); }
		}
	}

	return userAuthenticated;
}

void CClientConnection::Run()
{
	while(true)
	{
		if(userSocket && userAuthenticated) {
			
			/* socket is valid and user is authenticated, send any outstanding packets to the client connection then receive and process new ones  */

			while(userObject->getOutstandingPacketCount() && userSocket)
			{
				if(userObject->getNextPacket()->transmitPacket(userSocket))
				{
					userObject->destroyNextPacket(); // as this has been sent
				}
			}

			/* now check for new packets */

			CPacket* inboundPacket = getWaitingPacket();
			if(inboundPacket) { userObject->handleInboundPacket(inboundPacket); }

		}
		else
		{
			/* sleep for a long time if not socket or authentication, no point waisting time on this thread */
			Sleep(1000); 
		}

		Sleep(10);

	}
}



